import {
  ControlController,
  ITabExpPanelController,
  ITabExpPanelState,
  ITabExpPanelEvent,
  ITabExpPanelPagesState,
  calcNavParams,
  calcDeCodeNameById,
  INavViewMsg,
} from '@ibiz-template/runtime';
import { IDER1N, IDETabViewPanel, ITabExpPanel } from '@ibiz/model-core';

/**
 * 分页导航面板
 *
 * @export
 * @class TabExpPanelController
 * @extends {ControlController<IDETabExpPanel, ITabExpPanelState, ITabExpPanelEvent>}
 * @implements {ITabExpPanelController}
 */
export class TabExpPanelController
  extends ControlController<ITabExpPanel, ITabExpPanelState, ITabExpPanelEvent>
  implements ITabExpPanelController
{
  /**
   * 初始化state的属性
   *
   * @protected
   * @memberof TabExpPanelController
   */
  protected initState(): void {
    super.initState();
    this.state.tabPages = [];
    this.state.activeName = '';
  }

  /**
   * 创建完成
   *
   * @protected
   * @return {*}  {Promise<void>}
   * @memberof TabExpPanelController
   */
  async onCreated(): Promise<void> {
    await super.onCreated();
    this.layoutPanel = this.view.layoutPanel!;

    this.initTabPages();
  }

  /**
   * 初始化分页数据
   *
   * @memberof TabExpPanelController
   */
  initTabPages(): void {
    const viewPanel = this.model.controls as IDETabViewPanel[];
    const tabPages: ITabExpPanelPagesState[] = [];
    viewPanel.forEach((panel: IDETabViewPanel) => {
      tabPages.push({
        caption: panel.caption!,
        tabTag: panel.id!,
        class: panel.sysCss ? [panel.sysCss.cssName!] : [],
      });
    });
    this.state.tabPages = tabPages;
    if (tabPages.length > 0) {
      this.initDefaultPage();
    }
  }

  /**
   * 初始化默认分页
   *
   * @author zk
   * @date 2023-06-19 09:06:33
   * @memberof TabExpPanelController
   */
  initDefaultPage(): void {
    const initFirstPage = (): void => {
      this.state.activeName = this.state.tabPages[0].tabTag;
      this.handleTabChange();
    };
    if (!this.state.defaultTabName) {
      initFirstPage();
    } else {
      const activeTab = this.state.tabPages.find(
        item => item.tabTag === this.state.defaultTabName,
      );
      if (!activeTab) {
        initFirstPage();
      } else {
        this.state.activeName = activeTab.tabTag;
        this.changeToTab();
      }
    }
  }

  /**
   * 切换分页
   * @author lxm
   * @date 2023-08-10 05:37:26
   * @protected
   * @param {IDETabViewPanel} [tab=this.activeTabViewPanelModel!]
   */
  protected changeToTab(
    tab: IDETabViewPanel = this.activeTabViewPanelModel!,
  ): void {
    const navViewMsg = this.getNavViewMsg(tab);
    this.evt.emit('onNavViewChange', { navViewMsg });
  }

  /**
   * 当前激活tab模型
   *
   * @author zk
   * @date 2023-06-29 03:06:56
   * @readonly
   * @type {IDETabViewPanel}
   * @memberof TabExpPanelController
   */
  get activeTabViewPanelModel(): IDETabViewPanel {
    const { activeName } = this.state;
    const viewPanel = this.model.controls!.find(tab => tab.id === activeName);
    return viewPanel as IDETabViewPanel;
  }

  /**
   * 处理分页改变
   *
   * @memberof TabExpPanelController
   */
  async handleTabChange(): Promise<void> {
    if (this.activeTabViewPanelModel) {
      this.changeToTab();
    }
  }

  /**
   * 准备参数
   *
   * @param {IDETabViewPanel} tabViewPanel
   * @memberof TabExpPanelController
   */
  prepareParams(tabViewPanel: IDETabViewPanel): {
    context: IContext;
    params: IParams;
  } {
    const {
      navDER,
      navFilter,
      navigateContexts,
      navigateParams,
      appDataEntityId,
    } = tabViewPanel;
    const model = {
      deName: calcDeCodeNameById(appDataEntityId!),
      navFilter,
      pickupDEFName: (navDER as IDER1N)?.pickupDEFName,
      navContexts: navigateContexts,
      navParams: navigateParams,
    };
    const originParams = {
      context: this.context,
      params: this.params,
      data: {},
    };
    const { resultContext, resultParams } = calcNavParams(model, originParams);
    // 合并SrfNav
    const context = Object.assign(this.context.clone(), resultContext, {
      currentSrfNav: this.state.activeName,
    });
    const params = { ...this.params, ...resultParams };
    return { context, params };
  }

  /**
   *
   *
   * @author zk
   * @date 2023-06-29 03:06:41
   * @param {IDETabViewPanel} tabViewPanel
   * @return {*}  {Promise<INavViewMsg>}
   * @memberof TabExpPanelController
   */
  public getNavViewMsg(tabViewPanel: IDETabViewPanel): INavViewMsg {
    const { context, params } = this.prepareParams(tabViewPanel);
    return {
      key: tabViewPanel.codeName!.toLowerCase(),
      context,
      params,
      viewId: tabViewPanel.embeddedAppDEViewId,
    };
  }
}
